package com.ftg.learn.chapter8.linklist;

import lombok.Data;
import lombok.ToString;

/**
 * 问题
 *
 *  双链表
 *
 * @author kangjx
 * @version 1.0
 * @date 2023/8/8 下午3:25
 */
@ToString
public class Trouble {

    //头节点  用来做遍历超始
    private Node head;

    //尾节点  追加新元素的
    private Node tail;

    //总计
    private int count = 0;

    /**
     * 追加元素,速度，性能是不是高了
     *
     * @param x 数値
     */
    public void add(int x) {
        Node temp = new Node(x);
        if (head == null && tail == null) {
            head = temp;
            tail = head;
        } else {
            tail.setNext(temp);
            tail = tail.getNext();
        }
        count++;
    }

    /**
     * 在指定的index位置 插入x元素
     *
     * @param index 下标
     * @param x     插入的内容
     */
    public boolean insert(int index, int x) {

        //尾插
        if (index == count) {
            add(x);
            return true;
        }

        //头插
        if (index == 0) {
            //先有一个节点
            Node temp = new Node(x);
            temp.setNext(this.head);
            this.head = temp;
            this.count++;
            return true;
        }

        //中间插入
        Node temp = new Node(x);

        Node prev = this.getCurrentNode(index - 1);
        Node current = prev.getNext();

        temp.setNext(current);
        prev.setNext(temp);
        this.count++;
        return true;
    }

    /**
     * 有效元素个数
     *
     * @return
     */
    public int size() {
        return count;
    }

    /**
     * 删除某一个节点
     */
    public boolean del(int index) {
        if (index < 0 || index > count - 1) {
            throw new RuntimeException("位置 出错");
        }

        //真实的处理
        if (0 == index) {
            this.head = this.head.getNext();
            this.count--;
            return true;
        }

        //最后一个
        if (index == count - 1) {
            //tail = 尾tail的上一个节点
            this.tail = this.getCurrentNode(count - 2);
            //循环查找
            this.count--;
            return true;
        }

        //找到 index 上一个  和  下一个  上一个 = 下一个
        Node prevNode = this.getCurrentNode(index - 1);
        prevNode.setNext(prevNode.getNext().getNext());
        this.count--;
        return true;
    }

    /**
     * 用来查找下标为index的元素
     *
     * @param index 下标
     * @return 当前节点
     */
    private Node getCurrentNode(int index) {

        if (index < 0 || index > count - 1) {
            throw new RuntimeException("位置 出错");
        }

        if (head == null) {
            return null;
        }

        if (index == 0) {
            return head;
        }

        if (index == count - 1) {
            return tail;
        }

        int no = 0;
        Node temp = head;
        while (temp.getNext() != null && no++ != index) {
            temp = temp.getNext();
        }

        return temp;
    }

    /**
     * 获取头节点
     *
     * @return 节点
     */
    public Node getHead() {
        return getCurrentNode(0);
    }

    public Node getTail() {
        return getCurrentNode(count - 1);
    }

    @Data
    public class Node {
        //数値
        int val;

        //下一个节点
        Node next;

        //前指针
        Node prev;

        public Node(int val) {
            this.val = val;
        }

    }

    public static void main(String[] args) {
        Trouble t = new Trouble();
        t.add(1);
        t.add(2);
        t.add(3);
        t.add(4);

        System.out.println("没有删除以前的元素==>" + t);

        t.del(2);
        System.out.println("没有删除以后的元素==>" + t);
    }

}
